<template>
  <div class="sc-code-editor" :style="{'height':_height}">
    <textarea ref="textarea" v-model="contentValue"></textarea>
  </div>
</template>

<script>
//框架
import CodeMirror from '../../../lib/codemirror@5.65.5/codemirror.js'

//功能
import '../../../lib/codemirror@5.65.5/addon/selection/active-line.js'
import '../../../lib/codemirror@5.65.5/addon/display/autorefresh.js'

//语言
import '../../../lib/codemirror@5.65.5/mode/javascript/javascript.js'
import '../../../lib/codemirror@5.65.5/mode/sql/sql.js'

module.exports = {
  props: {
    modelValue: {
      type: String,
      default: ""
    },
    mode: {
      type: String,
      default: "javascript"
    },
    height: {
      type: [String, Number],
      default: 400,
    },
    options: {
      type: Object,
      default: () => {
      }
    },
    theme: {
      type: String,
      default: "idea"
    },
    readOnly: {
      type: Boolean,
      default: false
    },
  },
  data() {
    return {
      contentValue: this.modelValue,
      coder: null,
      opt: {
        autoRefresh: true,
        // 主题
        theme: this.theme,
        // 高亮当前行
        styleActiveLine: true,
        // 行号
        lineNumbers: true,
        // 自动换行
        lineWrapping: false,
        // Tab 缩进
        tabSize: 4,
        // 缩进单位
        indentUnit: 4,
        // 自动缩进
        indentWithTabs: true,
        // 语言
        mode: this.mode,
        // 只读
        readOnly: this.readOnly,
        ...this.options
      }
    }
  },
  computed: {
    _height() {
      return Number(this.height) ? Number(this.height) + 'px' : this.height
    },
  },
  watch: {
    modelValue(val) {
      this.contentValue = val
      if (val !== this.coder.getValue()) {
        this.coder.setValue(val)
      }
    }
  },
  mounted() {
    this.init()
    //获取挂载的所有modes
    //console.log(CodeMirror.modes)
  },
  methods: {
    init() {
      this.coder = Vue.markRaw(CodeMirror.fromTextArea(this.$refs.textarea, this.opt))
      this.coder.on('change', (coder) => {
        this.contentValue = coder.getValue()
        this.$emit('update:modelValue', this.contentValue)
      })
    },
    formatStrInJson(strValue) {
      return JSON.stringify(JSON.parse(strValue), null, 4)
    }
  }
}
</script>

<style scoped>
.sc-code-editor {
  font-size: 14px;
  border: 1px solid #ddd;
  line-height: 150%;
}

.sc-code-editor:deep(.CodeMirror) {
  height: 100%;
}

.CodeMirror-hints {
  z-index: 3000 !important;
}

.CodeMirror-lint-tooltip {
  z-index: 3000 !important;
}

</style>
